/// <reference name="MicrosoftAjax.js" />

Type.registerNamespace("SoulSolutions.Demo");

SoulSolutions.Demo.Map = function(element) {
    /// <summary>
    ///   The VE Map.
    ///   Supports load on demand
    /// </summary>
    /// <param name="element">The div element to be made into the VE map.</param>
    SoulSolutions.Demo.Map.initializeBase(this, [element]);
     
    this._map = null;
    this._latitude;
    this._longitude;
    this._mapMode;
    this._mapStyle;
    this._navigationControl3D;
    this._dashboard;
    this._dashboardSize;
    this._miniMap;
    this._miniMapXoffset;
    this._miniMapYoffset;
    this._miniMapSize;
    this._trafficLegend;
    this._trafficLegendX;
    this._trafficLegendY;
    this._traffic;
    this._trafficFlow;
    this._enableShapeDisplayThreshold;
    this._mouseWheelZoomToCenter;
    this._scaleBarDistanceUnit;
    this._shapesAccuracy;
    this._shapesAccuracyRequestLimit;
    this._tileBuffer;
    this._trafficLegendText;
    this._zoom;
    this._disambiguationDialog;
    this._onLoadMap;
    this._clearInfoBoxStyles;
    this._fixedMap;
    this._showMapModeSwitch;

    this._service;
    this._infoBox;
    this._isClustered;
    
    this._layer = null;
    this._currentBounds;
    
    this._infobox = null;
    
}

SoulSolutions.Demo.Map.prototype = {

    initialize : function() {
        /// <summary>
        ///   Initialises the Map.
        /// </summary>       
        SoulSolutions.Demo.Map.callBaseMethod(this, 'initialize') ;
        //setup map
        this._map = new VEMap(this.get_element().id);    
        if (this._dashboard) this._map.SetDashboardSize(this._dashboardSize);
        this._map.onLoadMap = Function.createDelegate(this, this._onLoadVEMap);        
        this._map.LoadMap(new VELatLong(this._latitude, this._longitude), this._zoom, this._mapStyle, this._fixedMap, this._mapMode, this._showMapModeSwitch, this._tileBuffer);
    }, 
    
    _onLoadVEMap: function() {
        /// <summary>
        ///   Executes on map load, sets the basic map properties.
        /// </summary>     
        this._map.SetScaleBarDistanceUnit(this._scaleBarDistanceUnit);
        this._map.EnableShapeDisplayThreshold(this._enableShapeDisplayThreshold);
        this._map.SetMouseWheelZoomToCenter(this._mouseWheelZoomToCenter);
        this._map.SetShapesAccuracy(this._shapesAccuracy);
        this._map.SetShapesAccuracyRequestLimit(this._shapesAccuracyRequestLimit);
        this._map.ShowDisambiguationDialog(this._disambiguationDialog);  
                
        if (!this._dashboard) {
            this._map.HideDashboard();
        }
        
        if (this._miniMap){
            this._map.ShowMiniMap(this._miniMapXoffset, this._miniMapYoffset, this._miniMapSize);
        }
        
        if (this._clearInfoBoxStyles) {
            this._map.ClearInfoBoxStyles();
        }
        
        if (!this._navigationControl3D) {
            this._map.Hide3DNavigationControl();
        }
        
        if (this._traffic) {
            this._map.LoadTraffic(this._trafficFlow);
            if (this._trafficLegend) {
                //TODO: support the default position, pass -1?
                this._map.ShowTrafficLegend(this._trafficLegendX, this._trafficLegendY)
                if (this._trafficLegendText) {
                    this._map.SetTrafficLegendText(this._trafficLegendText);
                }
            }
        }                  
        
        //custom infobox
        var infobox = document.createElement("div");
        infobox.id = "CustomInfoBox"
        infobox.className = "infoboxBR"
        document.body.appendChild(infobox);
        this._infobox = $create(SoulSolutions.Demo.CustomInfoBox, {"Service":this._service,"Map":this._map,"CentreX":490,"CentreY":290}, null, null, infobox);

        this._layer = new VEShapeLayer();         
        this._map.AddShapeLayer(this._layer);
        
        //setup the function to get new data whenever the map changes
        this._map.AttachEvent("onchangeview", Function.createDelegate(this, this.onChangeView));
        this._map.AttachEvent("onmouseover", Function.createDelegate(this, this._PinActivate));
        this._map.AttachEvent("onmouseout", Function.createDelegate(this, this._PinRestore));
        
        //Setup additional storage for shapes
        VEShape.prototype.Bounds = "";  
        VEShape.prototype.IconNormal = "";  
        VEShape.prototype.IconOver = "";
        VEShape.prototype.LineNormal = "";  
        VEShape.prototype.LineOver = "";
        VEShape.prototype.FillNormal = "";  
        VEShape.prototype.FillOver = "";
        //get the data for the default view
        this._GetPinData();
    },   
           
    ToggleClustered: function(clustered) {
        this._isClustered = clustered;
        this._GetPinData();    
    },
    
    onChangeView: function() {
        var bounds = Utility.GetBounds(this._map);
        if (!this._currentBounds || (this._currentBounds != bounds)) {
            this._GetPinData();
        }        
    }, 

    _GetPinData: function() {  
        /// <summary>
        ///   Get the latest map data from the webservice.
        /// </summary>
            
        var zoom;
        
        if (this._map.GetMapStyle() == VEMapStyle.Birdseye) {     
            //set zoomlevel      
            zoom = 19;
        }else {        
            //get zoomlevel
            zoom = this._map.GetZoomLevel();
        }
        this._currentBounds = Utility.GetBounds(this._map);
        if (this._zoom != zoom) {
            //clear existing pins
            this._layer.DeleteAllShapes();
            this._infobox.NotifyDeleteAllShapes();
            this._zoom = zoom;
        }
      
        //call webservice
        this._service.GetClusteredMapData(this._currentBounds, zoom, this._isClustered, Function.createDelegate(this, this._OnMapDataSucceeded), Utility.OnFailed);
    },

    _OnMapDataSucceeded: function(results) {
        /// <summary>
        ///   Receive data for map.
        /// </summary>  
        /// <param name="result">The webservice result object - Optomised CSV string</param>  
            
        this._layer.DeleteAllShapes();
        this._infobox.NotifyDeleteAllShapes();

        //decode pins
        var result=results.split(",")
        var locs = Utility.decodeLine(result[0]);
        
        var zoom = this._map.GetZoomLevel();
        var mapData = new Array();
               
        //add new pins
        for(var x = 0; x < locs.length; x++) {
            var loc = locs[x];
            var bounds = result[x+1];
            var recordcount = result[x+locs.length+1];
            
            if (zoom < 12) {
                var newShape = new VEShape(VEShapeType.Pushpin, loc); 
                newShape.Bounds = bounds;
                //set custom pin.
                if (recordcount > 50) newShape.IconNormal = "dot50";
                else if (recordcount > 20) newShape.IconNormal = "dot20";
                else if (recordcount > 10) newShape.IconNormal = "dot10";
                else newShape.IconNormal = "dot";
                newShape.IconOver = "<div class='" + newShape.IconNormal + " " + newShape.IconNormal + "over'></div>";
                newShape.IconNormal = "<div class='" + newShape.IconNormal + "'></div>";
                newShape.SetCustomIcon(newShape.IconNormal);
                mapData.push(newShape);            
            } else{           
                var newShape = new VEShape(VEShapeType.Polygon, Utility.GetCirclePoints(loc,0.5)[0]); 
                newShape.Bounds = bounds;
                newShape.SetIconAnchor(loc);
                newShape.HideIcon();
                newShape.LineNormal = new VEColor(245,202,88,0.6);  
                newShape.LineOver = new VEColor(235,161,31,0.6);
                newShape.FillNormal = new VEColor(245,202,88,0.2);
                newShape.FillOver = new VEColor(235,161,31,0.2); 
                newShape.SetFillColor(newShape.FillNormal);                 
                newShape.SetLineColor(newShape.LineNormal);                 
                this._layer.AddShape(newShape); 
            }         
        }
        
        if (mapData.length > 0)
        {
            this._layer.AddShape(mapData);
        }          
    }, 
    
    _PinActivate: function(e) {
        /// <summary>
        ///   Receives any mouse of event from VE
        /// </summary>  
        /// <param name="e">The MapEvent object</param>         
        if (e.elementID)
        {
            var popupShape = this._map.GetShapeByID(e.elementID)
              
            //verify new pin
            if (this._currentpin == null || popupShape.Bounds != this._currentpin.Bounds) {
                
                //restore mouseover effect on old pin if required, pin may no longer exist.
                if (this._currentpin) {
                    this._RestorePinEffect(this._currentpin);      
                }
                
                this._currentpin = popupShape;
                
                //mouseover effect
                this._ApplyPinEffect(this._currentpin); 
            }
            return true;
        }
    }, 
    
    _PinRestore: function(e) {
        /// <summary>
        ///   Receives any mouse of event from VE
        /// </summary>  
        /// <param name="e">The MapEvent object</param>         
        if (e.elementID)
        {
            var popupShape = this._map.GetShapeByID(e.elementID)      
            //verify new pin
            if (this._currentpin != null && popupShape.Bounds == this._currentpin.Bounds) {     
                //restore mouseover effect on old pin.
                this._RestorePinEffect(this._currentpin);      
                this._currentpin = null;
            }
            return true;
        }
    },
    
    _RestorePinEffect: function(pin) {
        if (pin.GetType() == VEShapeType.Pushpin) { 
            pin.SetCustomIcon(pin.IconNormal);
        } else {
            pin.SetFillColor(pin.FillNormal);                 
            pin.SetLineColor(pin.LineNormal); 
        }        
    },
    
    _ApplyPinEffect: function(pin) {
        if (pin.GetType() == VEShapeType.Pushpin) { 
            pin.SetCustomIcon(pin.IconOver);
        } else {
            pin.SetFillColor(pin.FillOver);                 
            pin.SetLineColor(pin.LineOver); 
        }        
    },    

    get_Service : function() {
        return this._service;
    }, 

    set_Service : function(value) {
        this._service = value;
    },
    
    get_InfoBoxArgs : function() {
        return this._infoBoxArgs;
    }, 

    set_InfoBoxArgs : function(value) {
        this._infoBoxArgs = value;
    },
    
    get_IsClustered : function() {
        return this._isClustered;
    }, 

    set_IsClustered : function(value) {
        this._isClustered = value;
    },        
    
    get_Latitude : function() {
        return this._latitude;
    }, 

    set_Latitude : function(value) {
        this._latitude = value;
    },
    
    get_Longitude : function() {
        return this._longitude;
    }, 

    set_Longitude : function(value) {
        this._longitude = value;
    },
    
    get_MapMode : function() {
        return this._mapMode;
    }, 

    set_MapMode : function(value) {
        this._mapMode = value;
    },
    
    get_MapStyle : function() {
        return this._mapStyle;
    }, 

    set_MapStyle : function(value) {
        this._mapStyle = value;
    },
    
    get_NavigationControl3D : function() {
        return this._navigationControl3D;
    }, 

    set_NavigationControl3D : function(value) {
        this._navigationControl3D = value;
    },
    
    get_Dashboard : function() {
        return this._dashboard;
    }, 

    set_Dashboard : function(value) {
        this._dashboard = value;
    },
    
    get_DashboardSize : function() {
        return this._dashboardSize;
    }, 

    set_DashboardSize : function(value) {
        this._dashboardSize = value;
    },
    
    get_MiniMap : function() {
        return this._miniMap;
    }, 

    set_MiniMap : function(value) {
        this._miniMap = value;
    },
    
    get_MiniMapXoffset : function() {
        return this._miniMapXoffset;
    }, 

    set_MiniMapXoffset : function(value) {
        this._miniMapXoffset = value;
    },
    
    get_MiniMapYoffset : function() {
        return this._miniMapYoffset;
    }, 

    set_MiniMapYoffset : function(value) {
        this._miniMapYoffset = value;
    },
    
    get_MiniMapSize : function() {
        return this._miniMapSize;
    }, 

    set_MiniMapSize : function(value) {
        this._miniMapSize = value;
    },
    
    get_TrafficLegend : function() {
        return this._trafficLegend;
    }, 

    set_TrafficLegend : function(value) {
        this._trafficLegend = value;
    },
    
    get_TrafficLegendX : function() {
        return this._trafficLegendX;
    }, 

    set_TrafficLegendX : function(value) {
        this._trafficLegendX = value;
    },
    
    get_TrafficLegendY : function() {
        return this._trafficLegendY;
    }, 

    set_TrafficLegendY : function(value) {
        this._trafficLegendY = value;
    },
    
    get_Traffic : function() {
        return this._traffic;
    }, 

    set_Traffic : function(value) {
        this._traffic = value;
    },
    
    get_TrafficFlow : function() {
        return this._trafficFlow;
    }, 

    set_TrafficFlow : function(value) {
        this._trafficFlow = value;
    },
    
    get_EnableShapeDisplayThreshold : function() {
        return this._enableShapeDisplayThreshold;
    }, 

    set_EnableShapeDisplayThreshold : function(value) {
        this._enableShapeDisplayThreshold = value;
    },
    
    get_MouseWheelZoomToCenter : function() {
        return this._mouseWheelZoomToCenter;
    }, 

    set_MouseWheelZoomToCenter : function(value) {
        this._mouseWheelZoomToCenter = value;
    },
    
    get_ScaleBarDistanceUnit : function() {
        return this._scaleBarDistanceUnit;
    }, 

    set_ScaleBarDistanceUnit : function(value) {
        this._scaleBarDistanceUnit = value;
    },
    
    get_ShapesAccuracy : function() {
        return this._shapesAccuracy;
    }, 

    set_ShapesAccuracy : function(value) {
        this._shapesAccuracy = value;
    },
    
    get_ShapesAccuracyRequestLimit : function() {
        return this._shapesAccuracyRequestLimit;
    }, 

    set_ShapesAccuracyRequestLimit : function(value) {
        this._shapesAccuracyRequestLimit = value;
    },
    
    get_TileBuffer : function() {
        return this._tileBuffer;
    }, 

    set_TileBuffer : function(value) {
        this._tileBuffer = value;
    },
    
    get_TrafficLegendText : function() {
        return this._trafficLegendText;
    }, 

    set_TrafficLegendText : function(value) {
        this._trafficLegendText = value;
    },
    
    get_Zoom : function() {
        return this._zoom;
    }, 

    set_Zoom : function(value) {
        this._zoom = value;
    }, 
    
    get_DisambiguationDialog : function() {
        return this._disambiguationDialog;
    }, 

    set_DisambiguationDialog : function(value) {
        this._disambiguationDialog = value;
    },
    
    get_OnLoadMap : function() {
        return this._onLoadMap;
    }, 

    set_OnLoadMap : function(value) {
        this._onLoadMap = value;
    },
    
    get_ClearInfoBoxStyles : function() {
        return this._clearInfoBoxStyles;
    }, 

    set_ClearInfoBoxStyles : function(value) {
        this._clearInfoBoxStyles = value;
    },
    
    get_FixedMap : function() {
        return this._fixedMap;
    }, 

    set_FixedMap : function(value) {
        this._fixedMap = value;
    },
    
    get_ShowMapModeSwitch : function() {
        return this._showMapModeSwitch;
    }, 

    set_ShowMapModeSwitch : function(value) {
        this._showMapModeSwitch = value;
    },  
    
    dispose : function() {
        /// <summary>
        ///   Dispose all events and objects.
        /// </summary>     
        if (this._map) {          
            this._map.Dispose();
            this._map = null;
        } 
        SoulSolutions.Demo.Map.callBaseMethod(this, 'dispose');
    }                           
}

SoulSolutions.Demo.Map.registerClass('SoulSolutions.Demo.Map', Sys.UI.Control);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

